package com.ityuwen.mengyagushi.search.service.impl;

import com.ityuwen.mengyagushi.album.client.AlbumInfoFeignClient;
import com.ityuwen.mengyagushi.album.client.CategoryFeignClient;
import com.ityuwen.mengyagushi.common.result.Result;
import com.ityuwen.mengyagushi.model.album.AlbumInfo;
import com.ityuwen.mengyagushi.model.album.BaseCategoryView;
import com.ityuwen.mengyagushi.model.user.UserInfo;
import com.ityuwen.mengyagushi.search.service.ItemService;
import com.ityuwen.mengyagushi.user.client.UserInfoFeignClient;
import com.ityuwen.mengyagushi.vo.album.AlbumStatVo;
import com.ityuwen.mengyagushi.vo.search.AlbumItemVo;
import com.ityuwen.mengyagushi.vo.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.concurrent.*;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class ItemServiceImpl implements ItemService {

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
//    @Qualifier("bean名称")
    private CategoryFeignClient categoryFeignClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private ExecutorService executorService;

    @Override
    public AlbumItemVo loadItemData(Long albumId) {

        AlbumItemVo albumItemVo = new AlbumItemVo();

        CompletableFuture<AlbumInfo> albumFuture = CompletableFuture.supplyAsync(() -> {
            // 1.根据专辑id查询专辑
            Result<AlbumInfo> albumInfoResult = this.albumInfoFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "专辑详情页：获取专辑信息失败！");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfoResult, "专辑详情页：对应的专辑不存在！");
            albumItemVo.setAlbumInfo(albumInfo);
            return albumInfo;
        }, executorService);

        CompletableFuture<Void> categoryFuture = albumFuture.thenAcceptAsync(albumInfo -> {
            // 2.根据三级分类id查询一二三级分类
            Result<BaseCategoryView> baseCategoryViewResult = this.categoryFeignClient.findBaseCategoryView(albumInfo.getCategory3Id());
            Assert.notNull(baseCategoryViewResult, "专辑详情页：获取三级分类失败！");
            BaseCategoryView baseCategoryView = baseCategoryViewResult.getData();
            albumItemVo.setBaseCategoryView(baseCategoryView);
        }, executorService);

        // 3.根据专辑id查询统计信息
        CompletableFuture<Void> statFuture = CompletableFuture.runAsync(() -> {
            Result<AlbumStatVo> albumStatResult = this.albumInfoFeignClient.findAlbumStatByAlbumId(albumId);
            Assert.notNull(albumStatResult, "专辑详情页：获取专辑统计信息失败！");
            AlbumStatVo albumStatVo = albumStatResult.getData();
            albumItemVo.setAlbumStatVo(albumStatVo);
        }, executorService);

        // 4.根据用户id查询主播信息
        CompletableFuture<Void> userFuture = albumFuture.thenAcceptAsync(albumInfo -> {
            Result<UserInfo> userInfoResult = this.userInfoFeignClient.getUserInfo(albumInfo.getUserId());
            Assert.notNull(userInfoResult, "专辑详情页：获取主播信息失败！");
            UserInfo userInfo = userInfoResult.getData();
            UserInfoVo userInfoVo = new UserInfoVo();
            BeanUtils.copyProperties(userInfo, userInfoVo);
            albumItemVo.setAnnouncer(userInfoVo);
        }, executorService);

        // 通过组合方法进行阻塞
        CompletableFuture.allOf(categoryFuture, statFuture, userFuture).join();



        return albumItemVo;
    }

    public static void main(String[] args) throws IOException {
//        new MyThread().start();
//        new Thread(() -> {
//            System.out.println("通过Runnable接口实现了多线程程序：" + Thread.currentThread().getName());
//        }).start();

//        FutureTask futureTask = new FutureTask<>(() -> {
//            System.out.println("1这是通过Callable接口实现了多线程程序：" + Thread.currentThread().getName());
//            int i = 1/0;
//            return "hello callable";
//        });
//        new Thread(futureTask).start();
//
//        try {
//            // 阻塞主线程，等待子任务执行完成才会执行
//            System.out.println("2子任务的执行结果：" + futureTask.get());
//        } catch (Exception e) {
//            System.out.println("3子任务的异常信息：" + e.getMessage());
//        }
//        ExecutorService executorService = new ThreadPoolExecutor(5, 10,
//                60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20),
//                Executors.defaultThreadFactory(),
//                new ThreadPoolExecutor.AbortPolicy());
//        Future<String> future = executorService.submit(() -> {
//            System.out.println("线程池执行异步任务：" + Thread.currentThread().getName());
//            int i = 1/0;
//            return "hello executor";
//        });
//
//        try {
//            System.out.println(future.get());
//        } catch (Exception e) {
//            System.out.println(e.getMessage());
//        }
//

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("CompletableFuture多线程任务" + Thread.currentThread().getName());
//            int i = 1/0;
            return "hello CompletableFuture!";
        });
        CompletableFuture<String> future1 = future.thenApplyAsync(t -> {
            System.out.println("===========thenApplyAsync=============");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t：" + t);
            return "hello thenApplyAsync";
        });
        CompletableFuture<Void> future2 = future.thenAcceptAsync(t -> {
            System.out.println("============thenAcceptAsync=============");
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t：" + t);
        });
        CompletableFuture<Void> future3 = future.thenRunAsync(() -> {
            System.out.println("============thenRunAsync=================");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("不获取，也不提供结果集");
        });

        CompletableFuture.anyOf(future1, future2, future3).join();

//                .exceptionally(t -> {
//            System.out.println("===============异常方法===============");
//            System.out.println("t: " + t);
//            return "exceptionally!";
//        }).whenCompleteAsync((t, u) -> {
//            System.out.println("==================计算完成时方法==================");
//            System.out.println("t: " + t);
//            System.out.println("u: " + u);
//        });

        System.out.println("main方法：" + Thread.currentThread().getName());

        System.in.read();
    }
}

class MyThread extends Thread{
    @Override
    public void run() {
//        new FileInputStream("xxxxx");
        System.out.println("通过继承Thread基类实现了多线程程序：" + Thread.currentThread().getName());
    }
}
